﻿using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Unicode;

namespace DataUp
{
    /// <summary>
    /// Json扩展类
    /// </summary>
    public static class JsonExtend
    {
        private static JsonSerializerOptions _options = null;

        static JsonExtend()
        {
            _options = new JsonSerializerOptions
            {
                Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(UnicodeRanges.All),
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            };
            _options.Converters.Add(new DateTimeNullableConverter());
            _options.Converters.Add(new DateTimeConverter());
        }


        public static string ToJson(this object obj)
        {
            return JsonSerializer.Serialize(obj, _options);
        }
        public static string ToJson(this object obj, string datetimeformats)
        {
            var options = new JsonSerializerOptions
            {
                Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(UnicodeRanges.All),
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            };
            options.Converters.Add(new DateTimeNullableConverter(datetimeformats));
            options.Converters.Add(new DateTimeConverter(datetimeformats));
            return JsonSerializer.Serialize(obj, _options);
        }
        public static T ToObject<T>(this string Json)
        {
            try
            {
                return Json == null ? default(T) : JsonSerializer.Deserialize<T>(Json, _options);
            }
            catch
            {
                return default(T);
            }
        }
        public static List<T> ToList<T>(this string Json)
        {
            try
            {
                return Json == null ? null : JsonSerializer.Deserialize<List<T>>(Json, _options);
            }
            catch
            {
                return null;
            }
        }
    }
    public class DateTimeConverter : JsonConverter<DateTime>
    {
        private string DateTimeFormat;
        public DateTimeConverter()
        {
            DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
        }

        public DateTimeConverter(string _dateTimeFormat)
        {
            DateTimeFormat = _dateTimeFormat;
        }
        public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return DateTime.Parse(reader.GetString());
        }

        public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
        }
    }

    public class DateTimeNullableConverter : JsonConverter<DateTime?>
    {
        private string DateTimeFormat;
        public DateTimeNullableConverter()
        {
            DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
        }

        public DateTimeNullableConverter(string _dateTimeFormat)
        {
            DateTimeFormat = _dateTimeFormat;
        }

        public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return string.IsNullOrEmpty(reader.GetString()) ? default(DateTime?) : DateTime.Parse(reader.GetString());
        }

        public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value?.ToString("yyyy-MM-dd HH:mm:ss"));
        }
    }
}
